﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using System.Net;
using System.Net.Mail;
using System.Net.Mime;
using Utilities;
using System.Security.AccessControl;
using BUS;
using AutoMail;
using System.Diagnostics;
namespace MacroApp
{
    public partial class FrmMain : Form
    {
        public FrmMain()
        {
            InitializeComponent();
           // LoadInfo();
           
        }
        #region  Declare
        private int idUser=0;
        private static string m_appPath = Path.GetDirectoryName(Application.ExecutablePath);
        private LogService m_log = new LogService(m_appPath);
        private string m_Income = string.Empty;
        private string m_Outcome = string.Empty;
        private string m_Bakup = string.Empty;
        List<KeyValuePair<String, String>> lstkv = new List<KeyValuePair<string, string>>();
        private string m_Subdefault = string.Empty;
        private string m_bodydefault = string.Empty;
        private string m_PassExcel = string.Empty;
        private string m_email = string.Empty;
        private string title = string.Empty;
        private string content = string.Empty;
        private string[] listMailTo=null;
        private string[] listMailCC=null;
        private string listExt = null;
        #endregion
        private void FrmMain_Load(object sender, EventArgs e)
        {
            if (Program.rule == 0)
            {
                btnNew.Visible = true;
            }
            Registrys.ProcessRegistry();
            timer1.Enabled = true;
        }

        #region Private
        /// <summary>
        /// Check size file < 10 MB return true else false
        /// </summary>
        /// <param name="appPath"></param>
        /// <returns></returns>
        private bool CheckSize(string appPath)
        {
            bool returnvalue = true;
            FileInfo fl = new FileInfo(appPath);
            string[] sizes = { "B", "KB", "MB", "GB" };
            double len = fl.Length;
            int order = 0;
            while (len >= 1024 && order + 1 < sizes.Length)
            {
                order++;
                len = len / 1024;
            }
            if (len > 10 && order == 2)
            {
                returnvalue = false;
            }
            fl = null;
            return returnvalue;
        }
        /// <summary>
        /// BackUp file MailInfo and delete it
        /// </summary>
        /// <param name="FilePath"></param>
        private void BackUpMailInfo(string FilePath)
        {
            try
            {
                string bakFile = FilePath.Replace(m_Income, string.Format(@"{0}\{1}", m_Bakup, DateTime.Now.ToString("yyyy-MM-dd")));
                string folder = bakFile.Substring(0, bakFile.LastIndexOf("\\"));

                if (!Directory.Exists(folder))
                {
                    Directory.CreateDirectory(folder);
                }
                bakFile = Path.Combine(folder, "MailInfo.txt");
                if (File.Exists(FilePath))
                {
                    File.Copy(FilePath, bakFile, true);
                    File.Delete(FilePath);
                }
            }
            catch (Exception ex)
            {
                m_log.WriteToLog(string.Format(@"{0} Bakup File Error with subject {1}. ", DateTime.Now, ex.Message), LogMessageType.Error);
            }
        }
      
        /// <summary>
        /// Create folder 
        /// </summary>
        /// <returns></returns>
        private bool CreatePath()
        {
            try
            {
                //System.Security.AccessControl.DirectorySecurity dSecurity = new DirectorySecurity();
                // Add the FileSystemAccessRule to the security settings. 
                //dSecurity.AddAccessRule(new FileSystemAccessRule("Everyone", FileSystemRights.FullControl, AccessControlType.Allow));
                //DirectoryInfo di = new DirectoryInfo(m_Income);
                //di.Create();

                if (!Directory.Exists(m_Income))
                {
                    Directory.CreateDirectory(m_Income);
                }

                if (!Directory.Exists(m_Outcome))
                {
                    Directory.CreateDirectory(m_Outcome);
                }

                if (!Directory.Exists(m_Bakup))
                {
                    Directory.CreateDirectory(m_Bakup);
                     string file = txtBackUp.Text + @"\" + "MailInfoDefault.txt";// Path.Combine(m_appPath, @"MailInfoDefault.txt");
                     if (!File.Exists(file))
                     {
                         using (StreamWriter sw = File.CreateText(file))
                         {
                             //  sw.WriteLine(string.Format(@"List Mail Error {0}", DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss")));
                             sw.WriteLine("Phòng kế toán - Công ty Tư vấn kế toán Hoàng Gia \n http://thanhlapcongty.com.vn -  Công ty tư vấn kế toàn Hoàng Gia kính gởi quý khách hàng, xin vui lòng xem các nội dung đính kèm, xin cảm ơn.");

                         }
                     }
                
                }
                if (!Directory.Exists(m_email))
                {
                    Directory.CreateDirectory(m_email);
                }
          

                return true;
            }
            catch (Exception ex)
            {
                m_log.WriteToLog(string.Format(@"{0} Create foldel Error with subject {1}.", DateTime.Now, ex.Message), LogMessageType.Error);
                return false;
            }
        }
        /// <summary>
        /// Delete Folder 
        /// </summary>
        /// <param name="appFolder"></param>
        private void DeleteFolder(string appFolder)
        {
            try
            {
                appFolder = string.Format(@"{0}\{1}", m_Income, appFolder);
                if (Directory.Exists(appFolder))
                {
                    Directory.Delete(appFolder, true);
                }
            }
            catch (Exception ex)
            {
                m_log.WriteToLog(string.Format(@"{0} Delete foldel {1} Error with subject {2}.", DateTime.Now, appFolder, ex.Message), LogMessageType.Error);
            }
        }
        /// <summary>
        /// BackUp File befor delete macro
        /// </summary>
        /// <param name="FilePath"></param>
        private void BakupFile(string FilePath)
        {
            try
            {

                string bakFile = FilePath.Replace(m_Income, m_Bakup);
                int index = bakFile.LastIndexOf("\\");
                string folder = bakFile.Substring(0, index);
                if (!Directory.Exists(folder))
                {
                    Directory.CreateDirectory(folder);
                }
               
                File.Copy(FilePath, bakFile, true);
            }
            catch (Exception ex)
            {
                m_log.WriteToLog(string.Format(@"{0} Bakup File Error with subject {1}. ", DateTime.Now, ex.Message), LogMessageType.Error);
            }
        }
        /// <summary>
        /// Get List File form Income
        /// </summary>
        /// <param name="path"></param>
        private void GetListFile(string path)
        {
            try
            {
                string[] files;
                string[] directories;
                files = Directory.GetFiles(path);
                foreach (string file in files)
                {
                    string ext = Path.GetExtension(file);
                    if (listExt.Contains(ext))// file.EndsWith(".xls") || file.EndsWith(".xlsx") || file.EndsWith(".pdf") || file.EndsWith(".doc") || file.EndsWith(".docx") || file.EndsWith(".txt") || file.EndsWith(".html"))
                    {
                        string emailAccount = path.Substring(path.LastIndexOf("\\") + 1);
                        if (Functions.IsValidEmail(emailAccount))
                        {
                            lstkv.Add(new KeyValuePair<String, String>(path.Substring(path.LastIndexOf("\\") + 1), file));
                        }
                        else {
                            m_log.WriteToLog(string.Format(@"{0} Mail Address Incorrect  with subject {1}. ", DateTime.Now, emailAccount), LogMessageType.Error);
                            break;
                        }                        
                    }
                }
                directories = Directory.GetDirectories(path);
                foreach (string directory in directories)
                {
                    // Process each directory recursively
                    GetListFile(directory);
                }
            }
            catch (Exception ex)
            {
                m_log.WriteToLog(string.Format(@"{0} GetFileSaveAsPath Error with subject {1}. ", DateTime.Now, ex.Message), LogMessageType.Error);
            }
        }
        /// <summary>
        /// return file save in Outcome after delete macro, use xls, xlsx, doc, docx, pdf
        /// </summary>
        /// <param name="currentFilePath"></param>
        /// <returns></returns>
        private string GetFileSaveAsPath(string currentFilePath)
        {
            string outFile = "";
            try
            {
                ///////// khong co' copy file qua outcome
                outFile = currentFilePath.Replace(m_Income, m_Outcome);
                int index = outFile.LastIndexOf("\\");
                string folder = outFile.Substring(0, index);
                if (!Directory.Exists(folder))
                {
                    Directory.CreateDirectory(folder);
                }
                //File.Copy(currentFilePath, outFile, true);
                return outFile;
            }
            catch (Exception ex)
            {
                m_log.WriteToLog(string.Format(@"{0} GetFileSaveAsPath Error with subject {1}. ", DateTime.Now, ex.Message), LogMessageType.Error);
                return string.Empty;
            }
        }
        /// <summary>
        /// delete macro of file excel or word or odf
        /// </summary>
        /// <param name="curFilePath"></param>
        /// <returns></returns>
        private bool DeleteMacroFile(string FilePath)
        {
            bool returnvalue = false;
            string e = Path.GetExtension(FilePath);
            try
            {
                if (listExt.Contains(e))
                {
                    switch (e.ToLower())
                    {

                        case ".xls":
                            this.BakupFile(FilePath);
                            Macro.DeleteVBMacroByService(FilePath, GetFileSaveAsPath(FilePath), ref returnvalue, m_PassExcel, m_appPath);
                            break;
                        case ".xlsx":
                            this.BakupFile(FilePath);
                            Macro.DeleteVBMacroByService(FilePath, GetFileSaveAsPath(FilePath), ref returnvalue, m_PassExcel, m_appPath);
                            break;
                        case ".doc":
                            this.BakupFile(FilePath);
                            Macro.DeleteMacroOfWordFile(FilePath, GetFileSaveAsPath(FilePath), ref returnvalue, m_PassExcel, m_appPath);
                            break;
                        case ".docx":
                            this.BakupFile(FilePath);
                            Macro.DeleteMacroOfWordFile(FilePath, GetFileSaveAsPath(FilePath), ref returnvalue, m_PassExcel, m_appPath);
                            break;
                        default:
                            this.BakupFile(FilePath);
                            try
                            {
                                File.Copy(FilePath, GetFileSaveAsPath(FilePath), true);
                                File.Delete(FilePath);
                                returnvalue = true;
                            }
                            catch
                            {
                                returnvalue = false;
                            }
                            break;

                    }
                }
               
                return returnvalue;
            }
            catch (Exception ex)
            {
                m_log.WriteLog(DateTime.Now, "DeleteCurrentMacroFile ", LogMessageType.Error, LogMessMode.Service, ex.Message);
                MessageBox.Show(ex.Message);
                return false;
            }
        }
        private void writeMailError(string mailError)
        {
           // string fileError = string.Format(@"{0}\{1}", m_Bakup, DateTime.Now.ToString("yyyy-MM-dd")); //string.Replace(m_Income, string.Format(@"{0}\{1}", m_Bakup, DateTime.Now.ToString("yyyy-MM-dd");
            string appPath = string.Format(@"{0}\{1}.txt", m_Bakup,"EmailError");
            if (!File.Exists(appPath))
            {
                using (StreamWriter sw = File.CreateText(appPath))
                {
                  //  sw.WriteLine(string.Format(@"List Mail Error {0}", DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss")));
                    sw.WriteLine(string.Format(@"Date Send :  {0} : {1} ", DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss"), mailError));

                }
            }
            else
            {
                using (System.IO.StreamWriter file = new System.IO.StreamWriter(appPath, true))
                {

                    file.WriteLine(string.Format(@"Date Send :  {0} :  {1} ", DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss "), mailError));
                }
            }
        }
        private void CreateMessage(string from, string to, List<string> Lstfile, string Subject, string Bodys, string MyUser, string Pass)
        {
            using (MailMessage msg = new MailMessage(from, to))
            {

                // Init mail                
                msg.SubjectEncoding = System.Text.Encoding.UTF8;
                msg.Subject = Subject;
                msg.BodyEncoding = System.Text.Encoding.UTF8;
                msg.Body = Bodys;
                if ( listMailCC!=null)
                {
                    for (int i = 0; i < listMailCC.Length; i++)
                    {
                        if (listMailCC[i] != null)
                        {
                            MailAddress copy = new MailAddress(listMailCC[i].ToString());
                            msg.CC.Add(copy);
                        }
                        else
                        {
                            listMailCC = null;
                            break;
                        }
                    }

                }

                foreach (string Info in Lstfile)
                {
                    if (File.Exists(Info))
                    {
                        if (CheckSize(Info))
                        {
                            msg.Attachments.Add(new Attachment(Info, MediaTypeNames.Application.Octet));
                        }
                    }
                }
                //smtp

                using (SmtpClient smtp = new SmtpClient())
                {
                    smtp.DeliveryMethod = SmtpDeliveryMethod.Network;

                    smtp.EnableSsl = (bool)useSslCheckBox.Checked;
                    smtp.Host = popServerTextBox.Text.Trim(); //"smtp.gmail.com";
                    smtp.Port = Int32.Parse(portTextBox.Text.Trim());
                    smtp.Timeout = Int32.Parse(txtTimeout.Text);
                    // add user va pass vao day.
                    System.Net.NetworkCredential credentials =
                            new System.Net.NetworkCredential(MyUser, Pass);
                    smtp.UseDefaultCredentials = true;
                    smtp.Credentials = credentials;
                    //Send
                    try
                    {

                        smtp.Send(msg);
                        // SmtpStatusCode status = new SmtpStatusCode(status);


                    }
                    catch (Exception ex)
                    {

                        writeMailError(to);

                        // m_log.WriteToLog(string.Format(@"{0} Send Error for mail with subject {1}. ", DateTime.Now, ex.Message), LogMessageType.Error);
                    }
                }
            }
        }
        private void loadEmailAdress()
        {
            string Path = string.Format(@"{0}\{1}.txt", m_Income, "ListMail");
            string[] readText = null;
            if (File.Exists(Path))
            {
                readText = System.IO.File.ReadAllLines(Path);
                int countExt = 0;
                int mailto=0;
                int mailcc=0;
                int countLine = readText.Length;
                listMailTo = new string[countLine];
                listMailCC = new string[countLine];
                title = "";
                for (int i = 1; i < countLine; i++)
                {
                    if (readText[i].Contains('*') && countExt != 3)
                    {
                        i=i+2;
                        countExt++;
                    }
                    if (countExt == 0)
                    {
                        
                       // listMailTo.Add(readText[i].ToString());
                        bool status = Functions.IsValidEmail(readText[i].ToString());
                        if (status)
                        {
                            listMailTo[mailto] = readText[i].ToString();
                        }
                        else
                        {
                            m_log.WriteToLog(string.Format(@"{0} Account mail Is Valid {1}. ", DateTime.Now, readText[i].ToString()), LogMessageType.Warning);
                        }
                        mailto++;
                        //listMailTo = readText[0].Split(new char[] { ';' });
                    }
                    else if (countExt == 1)
                    {
                        bool status = Functions.IsValidEmail(readText[i].ToString());
                        if (status)
                        {
                            listMailCC[mailcc] = readText[i].ToString();
                        }
                        else
                        {
                            m_log.WriteToLog(string.Format(@"{0} Account mail Is Valid {1}. ", DateTime.Now, readText[i].ToString()), LogMessageType.Warning);
                        }
                        mailcc++;
                    }
                    else if (countExt == 2)
                    {
                        title += readText[i];
                    }
                    else
                    {
                        content = ConvertArrayToString(readText, i);
                        Functions.AddColouredText(ConvertArrayToString(readText, i), rtxBody);
                        break;
                    }
                }
                if (title == "" || content == "")
                {
                    LoadMailInfo();
                }
                this.BackUpMailInfo(Path);    
            }
        }
        private void DMSendMail()
        {
            try
            {
                //
                
                if (!Directory.Exists(m_Income) || !Directory.Exists(m_Outcome))
                {
                    if (!CreatePath())
                    {
                        m_log.WriteToLog(string.Format(@"{0} Check CreatePath error {1}.", DateTime.Now, "DMSendMail"), LogMessageType.Error);
                        return;
                    }                    
                }

                //

               

                lstkv = new List<KeyValuePair<string, string>>();
                //
                bool delete = false;
                List<string> lstFileSaveAs = new List<string>();
                GetListFile(m_Income);
                for (int j = 0; j < lstkv.Count; j++)
                {
                    lblfileProgress.Text = lstkv[j].Value;
                    //                        
                    delete = DeleteMacroFile(lstkv[j].Value);
                    lstFileSaveAs.Add(GetFileSaveAsPath(lstkv[j].Value));
                }
                //      
                if (listMailTo[0]==null)
                {
                    listMailTo[0] = listMailCC[0];
                    for (int j = 0; j < (listMailCC.Length)-1; j++)
                    {
                        listMailCC[j] = listMailCC[j + 1];
                    }
                }
                for (int i = 0; i < listMailTo.Length; i++)
                {
                    if (listMailTo[i] != null)
                    {
                            CreateMessage(loginTextBox.Text.Trim(), listMailTo[i], lstFileSaveAs, title, content, loginTextBox.Text.Trim(), passwordTextBox.Text.Trim());
                    }
                    else
                    {
                        break;
                    }
                  
                }
                listMailTo = null;
                listMailCC = null;
                lblfileProgress.Text = "";
            }
            catch (Exception ex)
            {
                m_log.WriteToLog(string.Format(@"{0} Delete Error with subject {1}. ", DateTime.Now, ex.Message), LogMessageType.Error);
            }
        }
        private string ConvertArrayToString(string[] arr, int Position)
        {
            StringBuilder sw = new StringBuilder();
            for (int i = Position; i < arr.Length; i++)
            {
                {
                    sw.Append(string.Format(@" {0} ", arr[i]) + "\n");
                }
            }
            return sw.ToString();
        }
        private void LoadMailInfo()
        {
            string[] lines;
            string file = txtBackUp.Text + @"\" + "MailInfoDefault.txt";// Path.Combine(m_appPath, @"MailInfoDefault.txt");
            if (File.Exists(file))
            {
                lines = File.ReadAllLines(file);
                if (lines.Length > 1)
                {
                    title = lines[0];
                    content = ConvertArrayToString(lines, 1);
                    Functions.AddColouredText(ConvertArrayToString(lines, 0), rtxBody);
                }
                else
                {
                    Functions.AddColouredText("Phòng kế toán - Công ty Tư vấn kế toán Hoàng Gia \n http://thanhlapcongty.com.vn -  Công ty tư vấn kế toàn Hoàng Gia kính gởi quý khách hàng, xin vui lòng xem các nội dung đính kèm, xin cảm ơn.", rtxBody);
                }
            }
            else
            {
               
                title = "Phòng kế toán - Công ty Tư vấn kế toán Hoàng Gia";
                content = "http://thanhlapcongty.com.vn -  Công ty tư vấn kế toàn Hoàng Gia kính gởi quý khách hàng, xin vui lòng xem các nội dung đính kèm, xin cảm ơn.";
            }
        }
        /// <summary>
        /// Load Info and Load mail
        /// </summary>
        private void LoadAll()
        {
            this.LoadInfo(idUser);
            this.LoadMailInfo();
        }
        /// <summary>
        /// Load infomations
        /// </summary>
        private void LoadInfo(int UserId)
        {
            // This is only for faster debugging purposes
            // We will try to load in default values for the hostname, port, ssl, username and password from a file  



            var dt = MailInfoBUS.getMailInfoById(UserId);
                if (dt != null || dt.Rows.Count > 0)
                {
                  
                    // This describes how the MailLogin.txt file should look like
                    loginTextBox.Text = dt.Rows[0][2].ToString(); // Username
                    passwordTextBox.Text = Functions.Decrypt(dt.Rows[0][3].ToString(), true); // Password
                    popServerTextBox.Text = dt.Rows[0][4].ToString();  // Hostname
                    portTextBox.Text = dt.Rows[0][5].ToString(); // Port
                    txtTimeout.Text = dt.Rows[0][6].ToString();
                    if (bool.Parse(dt.Rows[0][7].ToString())==true)
                    {
                         useSslCheckBox.Checked=true;
                    }
                    else
                    {
                        useSslCheckBox.Checked=false;
                    }
                    listExt = dt.Rows[0][14].ToString();
                    //useSslCheckBox.Checked =  ?? "true"); // Whether to use SSL or not                    
                    txtDataFoder.Text = dt.Rows[0][8].ToString(); // Folder Data
                    txtOutCome.Text = dt.Rows[0][9].ToString(); //Out come
                    txtBackUp.Text = dt.Rows[0][10].ToString(); //Backup
                    txtPassWordExcel.Text = dt.Rows[0][12].ToString(); // Pass for excel
                    txtRepettion.Text = dt.Rows[0][11].ToString();
                    timer1.Enabled = false;
                    timer1.Interval = Int32.Parse(txtRepettion.Text.Trim());
                    timer1.Enabled = true;
                    // 0 la thu muc goc, 1 thu muc incom hoac outcom hoac backup, 2 la thu muc account email
                    m_Income = string.Format(@"{0}", txtDataFoder.Text.Trim());
                    m_Outcome = string.Format(@"{0}", txtOutCome.Text.Trim());
                    m_Bakup = string.Format(@"{0}", txtBackUp.Text.Trim());
                    m_appPath = string.Format(@"{0}", txtBackUp.Text.Trim());
                    txtRepettion.Text = dt.Rows[0][11].ToString(); // time of timer 
                    m_email = string.Format(@"{0}/{1}", txtDataFoder.Text.Trim(),loginTextBox.Text.Trim());
                    LoadMailInfo();
                    timer1.Interval = Int32.Parse(txtRepettion.Text.Trim());
         
                }
                else
                {
                    MessageBox.Show("Load Mail Config error!");
                }
      
        }
        private void checkMailError()
        {
            string appPath = string.Format(@"{0}\{1}.txt", m_Bakup, "EmailError");
            if (File.Exists(appPath))
            {
                string[] lines = System.IO.File.ReadAllLines(appPath);
                if (lines.Length == 0)
                {
                    linkMailError.Visible = false;
                }
                else
                {
                    linkMailError.Visible = true;
                }
            }
        }
        #endregion
        #region time Events
        private void timer1_Tick(object sender, EventArgs e)
        {
            checkMailError();
            var allUser = UserBUS.getAllUser();
            int count = allUser.Rows.Count;
            for (int items = 0; items < count; items++)
            {
                lblfileProgress.Text = string.Format(@"Start scan Folder and Delete Macro and sendmail at {0}", DateTime.Now);
                idUser = Convert.ToInt32(allUser.Rows[items][0]);
                LoadInfo(idUser);
                loadEmailAdress();
                DMSendMail();
                lblfileProgress.Text = string.Format(@"Finish at {0}", DateTime.Now);
            }
          
           
        }
        #endregion
        #region button Events
        private void btnHelp_Click(object sender, EventArgs e)
        {
            timer1.Enabled = false;
            FrmHelps frm = new FrmHelps();
            frm.ShowDialog();
            timer1.Enabled = true;
        }
        private void btnAccountSetting_Click(object sender, EventArgs e)
        {
            timer1.Enabled = false;
            Program.UserId = idUser;
            FrmAccountSettings frm = new FrmAccountSettings();
            frm.sender = new FrmAccountSettings.SEND(LoadAll);
            frm.ShowDialog();
            timer1.Enabled = true;
        }
        private void btncancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }
        #endregion

        private void btnNew_Click(object sender, EventArgs e)
        {
            FrmAddUser frm = new FrmAddUser();
            frm.Show();
        }

       

        private void linkMailError_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            string appPath = string.Format(@"{0}\{1}.txt", m_Bakup, "EmailError");
            if(File.Exists(appPath))
            {
                Process.Start("notepad.exe", appPath);
            }
        }

   

  
    }
}
